
package com.sbtr.business.calibration.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sbtr.business.calibration.entity.CalibrationDetails;
import com.sbtr.business.calibration.mapper.CalibrationDetailsMapper;
import com.sbtr.business.calibration.service.ICalibrationDetailsService;
import com.sbtr.common.PageDto;
import com.sbtr.constant.CalibrationConstant;
import com.sbtr.constant.ColumnConstant;
import com.sbtr.open.calibration.dto.*;
import com.sbtr.util.BeanCopyUtils;
import com.sbtr.util.PageDtoUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Executor;


/**
 * <p>
 * 标定集 服务实现类
 * </p>
 *

 */
@Transactional
@Service
public class CalibrationDetailsServiceImpl extends ServiceImpl<CalibrationDetailsMapper, CalibrationDetails>
		implements ICalibrationDetailsService {

	private static final Logger logger = LoggerFactory.getLogger(CalibrationDetailsServiceImpl.class);

	@Autowired
	CalibrationServiceTxtImpl calibrationTxtService;

	@Autowired
	@Lazy
	private ICalibrationDetailsService calibrationDetailsService;


	@Resource(name = "asyncTxtExecutor")
	Executor asyncExecutor;

	@Override
	public CalibrationDetailsDto save(CalibrationDetailsDto dto) {
		CalibrationDetails data = BeanCopyUtils.copyProperties(dto, CalibrationDetails.class);
		if(dto.getId() == null) {
			save(data);
			dto.setId(data.getId());
		}else {
			return BeanCopyUtils.copyProperties(data, CalibrationDetailsDto.class);
		}
		return dto;
	}

	@Override
	public CalibrationDetailsDto findById(Long id) {
		return BeanCopyUtils.copyProperties(getById(id), CalibrationDetailsDto.class);
	}

	@Override
	public CalibrationDetailsDto update(CalibrationDetailsDto dto) {
		CalibrationDetails calibrationDetail = BeanCopyUtils.copyProperties(dto,CalibrationDetails.class);
		calibrationDetail.setId(dto.getId());
		updateById(calibrationDetail);
		return dto;

	}

	/**
	 * 数据标注模块：
	 * 分页查询我被分配的任务列表
	 * 1.以 “任务完成者名称 ”进行查询
	 * @param pro
	 * @return
	 */
	@Override
	public PageDto<CalibrationDetailsDto> searchDetails(CalibrationSearchDetailsDto pro){

		IPage<CalibrationDetails> page = new Page<>();
		page.setSize(pro.getPageSize());
		page.setCurrent(pro.getPage());
		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		wrapper.eq(ColumnConstant.IS_AVAILABLE, 1);
		if (null != pro.getId()) {
			wrapper.like(ColumnConstant.ID, pro.getId());
		}
		if (StringUtils.isNotEmpty(pro.getCalibrationName())) {
			wrapper.like(ColumnConstant.CALIBRATION_NAME, pro.getCalibrationName());
		}

		if (StringUtils.isNotEmpty(pro.getFinisher())) {
			wrapper.eq("finisher", pro.getFinisher());
		}

		if (StringUtils.isNotEmpty(pro.getCreater())) {
			wrapper.eq("creater", pro.getCreater());
		}

		if( null != pro.getStatus() && !pro.getStatus().isEmpty()) {
			wrapper.in(ColumnConstant.STATUS, pro.getStatus());
		}

		if( null != pro.getPriority() && !pro.getPriority().isEmpty()) {
			wrapper.in(ColumnConstant.TASK_PRIORITY, pro.getPriority());
		}

		if( null != pro.getTaskType() && !pro.getTaskType().isEmpty()) {
			wrapper.in(ColumnConstant.TASK_TYPE, pro.getTaskType());
		}

		if (null != pro.getTotalCount()) {
			wrapper.eq(ColumnConstant.TOTAL_COUNT, pro.getTotalCount());
		}

		if (null != pro.getClassifyCount()) {
			wrapper.eq(ColumnConstant.CLASSIFY_COUNT, pro.getClassifyCount());
		}

		if (null != pro.getCreateTime()) {
			Date createTimeTo = pro.getCreateTime(); //取时间
			Calendar calendar = new GregorianCalendar();
			calendar.setTime(createTimeTo);
			calendar.add(calendar.DATE,1); //把日期往后增加一天,整数  往后推,负数往前移动
			createTimeTo=calendar.getTime(); //这个时间就是日期往后推一天的结果
			wrapper.between(ColumnConstant.CREATE_TIME, pro.getCreateTime(), createTimeTo);
		}

		if (null != pro.getFinishedTime()) {
			Date createTimeTo = pro.getFinishedTime(); //取时间
			Calendar calendar = new GregorianCalendar();
			calendar.setTime(createTimeTo);
			calendar.add(calendar.DATE,1); //把日期往后增加一天,整数  往后推,负数往前移动
			createTimeTo=calendar.getTime(); //这个时间就是日期往后推一天的结果
			wrapper.between(ColumnConstant.FINISHED_TIME, pro.getFinishedTime(), createTimeTo);
		}

		if (null != pro.getUpdateTime()) {
			Date createTimeTo = pro.getUpdateTime(); //取时间
			Calendar calendar = new GregorianCalendar();
			calendar.setTime(createTimeTo);
			calendar.add(calendar.DATE,1); //把日期往后增加一天,整数  往后推,负数往前移动
			createTimeTo=calendar.getTime(); //这个时间就是日期往后推一天的结果
			wrapper.between(ColumnConstant.UPDATE_TIME, pro.getUpdateTime(), createTimeTo);
		}

		wrapper.orderByDesc("id");
		page = page(page, wrapper);
		PageDto<CalibrationDetailsDto> pageDto = PageDtoUtils.getPageDtoByIPage(page, CalibrationDetailsDto.class);
		return pageDto;
	}

	@Override
	public PageDto<CalibrationDetailsDto> searchDetailsByCalibrationId(CalibrationSearchByDetailsDto pro){

		IPage<CalibrationDetails> page = new Page<>();
		page.setSize(pro.getPageSize());
		page.setCurrent(pro.getPage());
		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		if (null != pro.getId())
			wrapper.eq("calibration_id", pro.getId());

		wrapper.orderByDesc("id");
		page = page(page, wrapper);
		PageDto<CalibrationDetailsDto> pageDto = PageDtoUtils.getPageDtoByIPage(page, CalibrationDetailsDto.class);
		return pageDto;
	}



	// 更新文本类型的标定统计数据
	@Override
	public boolean updateCalibrationDetailsTxtCount(CalibrationDto dto) {

		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		Long calibrationIds=dto.getId();
		wrapper.in("calibration_id", calibrationIds);
		List<CalibrationDetails> list = list(wrapper);

		if (list != null && !list.isEmpty()) {

			//统计每个的任务所有人的数据
			List<CalibrationCountByFinisherDto>  countTxtDto=calibrationTxtService.countTaskByCalibrationIds(calibrationIds);

			for(CalibrationDetails details:list){
				for(CalibrationCountByFinisherDto tem:countTxtDto){
					if(details.getFinisher().equals(tem.getFinisher())){
						details.setCompleted(tem.getCompleted());
						if(tem.getUncompleted()==0){
							details.setCompleted(tem.getCompleted());
							details.setStatus(CalibrationConstant.TASK_STATUS_COMPLETED);
						}else{
							details.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
						}
					}
				}
				CalibrationDetailsDto calibrationDetail = BeanCopyUtils.copyProperties(details,CalibrationDetailsDto.class);
				calibrationDetailsService.update(calibrationDetail);
			}
			return true;
		}else{
			return false;
		}

		}




	@Override
	public boolean batchSave(List<CalibrationDetailsDto> dtos) {
		List<CalibrationDetails> materialtxt = BeanCopyUtils.copyProperties(dtos, CalibrationDetails.class);
		if (materialtxt.size()<10000){
			saveBatch(materialtxt);
		}else{
			int num = 2000;
			int k = 0;
			List<CalibrationDetails> saveList = new ArrayList<>();;
			for (int i = 0; i < materialtxt.size(); i++) {
				k++;
				saveList.add(materialtxt.get(i));
				if (k == num || i-1 == materialtxt.size()){
					k = 0;
					batchSaveAsync(saveList);
					saveList = new ArrayList<>();
				}
			}
		}
		return true;
	}

	@Async("asyncTxtExecutor")
	public void batchSaveAsync(List<CalibrationDetails> materialTxtList) {
		asyncExecutor.execute(new CalibrationDetailsServiceImpl.batchSaveThread(materialTxtList));
	}
	@Async
	class batchSaveThread implements Runnable {

		private List<CalibrationDetails> materialTxtList;

		public batchSaveThread(List<CalibrationDetails> list){
			this.materialTxtList = list;
		}

		@Override
		public void run() {
			saveBatch(materialTxtList);
		}
	}


	@Override
	public List<CalibrationDetailsDto> searchDetailsCalibrationId(Long calibrationId){
		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		wrapper.eq("calibration_id", calibrationId);
		return BeanCopyUtils.copyProperties(list(wrapper), CalibrationDetailsDto.class);
	}

	@Override
	public CalibrationDetailsDto searchDetailsFinisher(Long calibrationId, String finisher){
		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		wrapper.eq("calibration_id", calibrationId);
		wrapper.eq("finisher", finisher);
//		wrapper.eq(ColumnConstant.IS_AVAILABLE, 1);
		return BeanCopyUtils.copyProperties(getOne(wrapper), CalibrationDetailsDto.class);
	}

	@Override
	public boolean updateIsAvailable(List<Long> idList){
		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		wrapper.in("calibration_id", idList);
		List<CalibrationDetails> CalibrationDetailsList = list(wrapper);
		for(CalibrationDetails calibrationDetails: CalibrationDetailsList){
			baseMapper.updateIsAvailableById(calibrationDetails.getId());
		}
		return true;
	}

	@Override
	public CalibrationProgressDto searchProgressByFinisher(CalibrationSearchByDetailsDto dto){

		QueryWrapper<CalibrationDetails> wrapper = new QueryWrapper<>();
		wrapper.eq("finisher", dto.getFinisher());
		wrapper.eq("calibration_id", dto.getId());
		List<CalibrationDetails> calibrationDetails=list(wrapper);
		CalibrationProgressDto dtos=new CalibrationProgressDto();
		if (calibrationDetails.size() == 0) {
			return null;
		}else{
			int totalcount=calibrationDetails.get(0).getTotalCount();
			int completed=calibrationDetails.get(0).getCompleted();
			dtos.setFinisher(dto.getFinisher());
			dtos.setId(dto.getId());
			Double progress=(double)completed/totalcount;
			dtos.setProgress(progress);
			return dtos;
		}

	}




}